package com.juyu.miliao.scheduler.dao.redis;

import com.alibaba.fastjson.JSONObject;
import com.juyu.miliao.common.constant.GiftWallRedisKey;
import com.juyu.miliao.common.util.DateUtil;
import com.juyu.miliao.scheduler.domin.GiftSpend;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import javax.sound.midi.Soundbank;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;


/**
 * 礼物墙Redis
 *
 * @author xuanqicheng
 * @create 2019-18-14:32
 */
@Repository
public class GiftWallRedisDao {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    public void setGiftWallListInfo(GiftSpend giftSpend) {

        LocalDate localDate = giftSpend.getCreateTime().toLocalDate();

        //当前日期是第几周
        int weeksByYear = DateUtil.getWeeksByYear(1, localDate);

        String key = GiftWallRedisKey.GIFT_WALL_NEW_LIST_ZSET+localDate.getYear()+":"+weeksByYear;


        int week=giftSpend.getCreateTime().getDayOfWeek().getValue();

        String timeBySecond = getTimeBySecond(giftSpend.getCreateTime().getHour(),giftSpend.getCreateTime().getMinute(),
                giftSpend.getCreateTime().getSecond());

        long score = Long.parseLong(giftSpend.getSpend()+""+week+timeBySecond);

        stringRedisTemplate.opsForZSet().add(key,JSONObject.toJSONString(giftSpend),score);

        stringRedisTemplate.expire(key,15, TimeUnit.DAYS);

    }

    /**
     * 兼容老版本，版本小于1.4.3使用
     *
     * @param time
     * @param giftSpend
     */
    public void setOldGiftWallListInfo(String time, GiftSpend giftSpend) {

        int max = getMaxGift(time);

        String key = GiftWallRedisKey.GIFT_WALL_ZSET + time;

        String maxKey = GiftWallRedisKey.GIFT_WALL_MAX_ZSET + time;

        if (giftSpend.getSpend() > max) {

            setMaxGift(time, giftSpend.getSpend());

            setGiftWallMaxInfo(giftSpend, maxKey);

            Set<String> set = getGiftWallMaxInfo(maxKey, max);

            if (set != null && set.size() > 0) {

                Set<ZSetOperations.TypedTuple<String>> hashSet = new HashSet<>();

                List<String> list = new ArrayList<>(set);


                for (String str : list) {

                    JSONObject json = JSONObject.parseObject(str);

                    GiftWallZset giftWallZset = new GiftWallZset(str, json.getIntValue("spendId"));

                    hashSet.add(giftWallZset);
                }

                if (hashSet.size() > 0) {

                    long expireTime = DateUtil.getTheRemainingTimesOfTheDay(LocalDateTime.now().plusDays(1).withHour(0)
                            .withMinute(0).withSecond(0).withNano(0), TimeUnit.MINUTES);

                    stringRedisTemplate.opsForZSet().add(key, hashSet);

                    stringRedisTemplate.expire(key, expireTime, TimeUnit.MINUTES);
                }

            }

        } else if (giftSpend.getSpend() == max) {

            setMaxGift(time, giftSpend.getSpend());

            setGiftWallMaxInfo(giftSpend, maxKey);

        } else {
            setGiftWallInfo(giftSpend, key);
        }


    }


    /**
     * 设置礼物墙，根据id进行存储
     *
     * @param giftSpend
     * @param key
     */
    private void setGiftWallInfo(GiftSpend giftSpend, String key) {
        stringRedisTemplate.opsForZSet().add(key, JSONObject.toJSONString(giftSpend), giftSpend.getSpendId());

        LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0)
                .withMinute(0).withSecond(0).withNano(0);

        stringRedisTemplate.expire(key, DateUtil.getTheRemainingTimesOfTheDay(midnight, TimeUnit.MINUTES),
                TimeUnit.MINUTES);
    }


    /**
     * 设置礼物墙，根据金币数进行存在
     *
     * @param giftSpend
     * @param key
     */
    private void setGiftWallMaxInfo(GiftSpend giftSpend, String key) {

        LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0)
                .withMinute(0).withSecond(0).withNano(0);

        stringRedisTemplate.opsForZSet().add(key, JSONObject.toJSONString(giftSpend), giftSpend.getSpend());

        long expireTime = DateUtil.getTheRemainingTimesOfTheDay(midnight, TimeUnit.MINUTES);

        stringRedisTemplate.expire(key, expireTime, TimeUnit.MINUTES);
    }

    private Set<String> getGiftWallMaxInfo(String key, int gold) {

        Set<String> set = stringRedisTemplate.opsForZSet().rangeByScore(key, gold, gold);

        return set;
    }


    /**
     * 获取最大金币数
     *
     * @param time
     * @return
     */
    private int getMaxGift(String time) {

        String temp = stringRedisTemplate.opsForValue().get(GiftWallRedisKey.GIFT_MAX_INFO + time);

        if (!StringUtils.isEmpty(temp)) {

            return Integer.parseInt(temp);

        } else {

            return 0;

        }

    }

    /**
     * 设置最大金币数
     *
     * @param time
     * @param max
     */
    private void setMaxGift(String time, int max) {

        String key = GiftWallRedisKey.GIFT_MAX_INFO + time;

        LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0)
                .withMinute(0).withSecond(0).withNano(0);

        long expireTime = DateUtil.getTheRemainingTimesOfTheDay(midnight, TimeUnit.MINUTES);

        stringRedisTemplate.opsForValue().set(key, Integer.toString(max), expireTime, TimeUnit.MINUTES);

    }


    class GiftWallZset implements ZSetOperations.TypedTuple<String> {

        String value;

        double score;

        public GiftWallZset(String value, double score) {

            this.value = value;

            this.score = score;
        }

        @Override
        public String getValue() {
            return value;
        }

        @Override
        public Double getScore() {
            return score;
        }

        @Override
        public int compareTo(ZSetOperations.TypedTuple<String> o) {

            GiftWallZset o1 = (GiftWallZset) o;

            return new Double(this.score).compareTo(o1.getScore());

        }
    }


    /**
     * 根据小时，分钟，秒数获取5位秒数，位数不足用0补全
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    private String getTimeBySecond(int hour, int minute, int second) {

        int hourBySecond = hour * 3600;

        int minuteBySecond = minute * 60;

        String time = Integer.toString(hourBySecond + minuteBySecond + second);

        if(time.length()==5){
            return time;
        }else {
            switch (5 - time.length()) {
                case 4:
                    time = "0000" + time;
                    break;
                case 3:
                    time = "000" + time;
                    break;
                case 2:
                    time = "00" + time;
                    break;
                case 1:
                    time = "0" + time;
                    break;
                default:
                    time = "00000";
            }
            return time;
        }

    }

}
